package com.example.gzysmartcity.viewmodel;

import android.util.Log;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.blankj.utilcode.util.ThreadUtils;
import com.example.gzysmartcity.repository.model.CityBus;
import com.example.gzysmartcity.repository.model.CityBusLine;
import com.example.gzysmartcity.repository.model.CityBusLineAndStop;
import com.example.gzysmartcity.repository.model.CityBusLineStop;
import com.example.gzysmartcity.repository.model.MyCityBus;
import com.example.gzysmartcity.repository.remote.State;
import com.example.gzysmartcity.utils.NetworkUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class BusListViewModel extends ViewModel {
    private final MutableLiveData<State> busLivedata = new MutableLiveData<>();
    private List<CityBus.DataBean> busList;
    private List<CityBusLineStop.DataBean> busStopList;
    private List<CityBusLineAndStop.DataBean> cityBusLineAndStopList;
    private List<MyCityBus> mMyCityBusList;
    private String lineName;

    public String getLineName() {
        return lineName;
    }

    public void getCityBusLine(int id) {
        ThreadUtils.executeByCached(new ThreadUtils.Task<CityBusLine>() {
            @Override
            public CityBusLine doInBackground() throws Throwable {
                lineName = null;
                return NetworkUtil.getInstance().get("CityBusLine/getAll?", null, CityBusLine.class, 0);
            }

            @Override
            public void onSuccess(CityBusLine result) {
                lineName = result.getData().stream().filter(a -> a.getId() == id).findFirst().get().getCityBusLineName();
                busLivedata.setValue(State.SUCCESS);
            }

            @Override
            public void onCancel() {
            }

            @Override
            public void onFail(Throwable t) {
                busLivedata.postValue(State.FAIL);
            }
        });
    }

    public void getBusData() {
        ThreadUtils.executeByCached(new ThreadUtils.Task<CityBus>() {
            @Override
            public CityBus doInBackground() throws Throwable {
                return NetworkUtil.getInstance().get("CityBus/getAll?", null, CityBus.class, 0);
            }

            @Override
            public void onSuccess(CityBus result) {
                busList = result.getData();
                getCityBusLineAndStop();
            }

            @Override
            public void onCancel() {
                busLivedata.postValue(State.FAIL);
            }

            @Override
            public void onFail(Throwable t) {

            }
        });
    }

    private void getCityBusLineAndStop() {
        ThreadUtils.executeByCached(new ThreadUtils.Task<CityBusLineAndStop>() {
            @Override
            public CityBusLineAndStop doInBackground() throws Throwable {
                return NetworkUtil.getInstance().get("CityBusLineAndStop/getAll?", null, CityBusLineAndStop.class, 0);
            }

            @Override
            public void onSuccess(CityBusLineAndStop result) {
                cityBusLineAndStopList = result.getData();
                getBusStopData();
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onFail(Throwable t) {
                busLivedata.postValue(State.FAIL);
            }
        });
    }

    private void getBusStopData() {
        ThreadUtils.executeByCached(new ThreadUtils.Task<CityBusLineStop>() {
            @Override
            public CityBusLineStop doInBackground() throws Throwable {
                return NetworkUtil.getInstance().get("CityBusLineStop/getAll?", null, CityBusLineStop.class, 0);
            }

            @Override
            public void onSuccess(CityBusLineStop result) {
                busStopList = result.getData();
                dataProcessing();

            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onFail(Throwable t) {
                busLivedata.postValue(State.FAIL);
            }
        });
    }

    private void dataProcessing() {
        ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Object>() {
            @Override
            public Object doInBackground() {
                mMyCityBusList = new ArrayList<>();
                for (CityBus.DataBean dataBean : busList) {
                    String currStopName = null;
                    String nextStopName = null;
                    //
                    int currBusLineStop = dataBean.getCurrBusLineStop();
                    int nextBusLineStop = dataBean.getNextBusLineStop();
                    int cityBusLineId = dataBean.getCityBuslineId();
                    int direction = dataBean.getDrection();
                    //
                    Supplier<Stream<CityBusLineAndStop.DataBean>> dataBeanStream = () -> cityBusLineAndStopList.stream()
                            .filter(a -> a.getCityBuslineId() == cityBusLineId);

                    List<CityBusLineAndStop.DataBean> dir1BusStop = dataBeanStream.get().filter(a -> a.getDrection() == 1).collect(Collectors.toList());
                    List<CityBusLineAndStop.DataBean> dir2BusStop = dataBeanStream.get().filter(a -> a.getDrection() == 2).collect(Collectors.toList());

                    //
                    int firstBusLineStop = dataBeanStream.get().filter(a -> a.getType() == 1 && a.getDrection() == 1).findFirst().get().getCityBuslineStopId();
                    int firstBusLineStop2 = dataBeanStream.get().filter(a -> a.getType() == 1 && a.getDrection() == 2).findFirst().get().getCityBuslineStopId();
                    int lastBusLineStop = dataBeanStream.get().filter(a -> a.getType() == 2 && a.getDrection() == 1).findFirst().get().getCityBuslineStopId();
                    int lastBusLineStop2 = dataBeanStream.get().filter(a -> a.getType() == 2 && a.getDrection() == 2).findFirst().get().getCityBuslineStopId();
                    List<CityBusLineStop.DataBean> lineStop = busStopList.stream().filter(a -> a.getCityBuslineId() == cityBusLineId).collect(Collectors.toList());
                    List<CityBusLineStop.DataBean> dir1LineStop;
                    List<CityBusLineStop.DataBean> dir2LineStop;
                    //公车站名
                    dir1LineStop = lineStop.subList(0, dir1BusStop.size() - 2);
                    dir2LineStop = lineStop.subList(lineStop.size() / 2, lineStop.size());
                    Collections.reverse(dir2LineStop);
                    ArrayList<String> dir1StopNameList = new ArrayList<>();
                    dir1StopNameList.add("起始站");
                    for (CityBusLineStop.DataBean bean : dir1LineStop) {
                        dir1StopNameList.add(bean.getCityBusLineStopName());
                    }
                    dir1StopNameList.add("终点站");
                    //
                    if (direction == 1) {
                        if (currBusLineStop == firstBusLineStop) {
                            currStopName = "起始站";
                        } else if (currBusLineStop == lastBusLineStop) {
                            currStopName = "终点站";
                        } else {
                            //如果当前的busStopId==nextBusLineStop，获取站点名称
                            for (int i = 1; i < dir1BusStop.size() - 1; i++) {
                                CityBusLineAndStop.DataBean dataBean1 = dir1BusStop.get(i);
//                                Log.i("TAG", "doInBackground: " + dataBean1.getType());
                                int cityBuslineStopId = dataBean1.getCityBuslineStopId();

                                if (cityBuslineStopId == nextBusLineStop) {
                                    Log.i("TAG", "doInBackground1: " + cityBuslineStopId + "," + nextBusLineStop);
                                    nextStopName = dir1LineStop.get(i - 1).getCityBusLineStopName();
                                } else if (cityBuslineStopId == currBusLineStop) {
                                    Log.i("TAG", "doInBackground2: " + cityBuslineStopId + "," + currBusLineStop);
                                    currStopName = dir1LineStop.get(i - 1).getCityBusLineStopName();
                                }
                            }
                            Log.i("TAG", "doInBackground3: " + currStopName + nextStopName);

                        }
                    } else {
                        if (currBusLineStop == firstBusLineStop2) {
                            currStopName = "终点站";
                        } else if (currBusLineStop == lastBusLineStop2) {
                            currStopName = "起始站";
                        } else {
                            for (int i = 1; i < dir2BusStop.size() - 1; i++) {
                                CityBusLineAndStop.DataBean dataBean1 = dir2BusStop.get(i);
                                int cityBuslineStopId = dataBean1.getCityBuslineStopId();
                                if (cityBuslineStopId == nextBusLineStop) {
                                    Log.i("TAG", "do2InBackground1: " + cityBuslineStopId + "," + nextBusLineStop);
                                    nextStopName = dir2LineStop.get(i - 1).getCityBusLineStopName();
                                } else if (cityBuslineStopId == currBusLineStop) {
                                    Log.i("TAG", "do2InBackground2: " + cityBuslineStopId + "," + currBusLineStop);
                                    currStopName = dir2LineStop.get(i - 1).getCityBusLineStopName();
                                }
                            }
                            Log.i("TAG", "do2InBackground3: " + currStopName + nextStopName);
                        }
                    }
                    mMyCityBusList.add(new MyCityBus(dataBean.getCityCarName(), currStopName, nextStopName,
                            dataBean.getDistance(), dataBean.getCapacity(), direction,
                            dataBean.getCityBuslineId(), dir1StopNameList));
                }
                return null;
            }

            @Override
            public void onSuccess(Object result) {
                busLivedata.setValue(State.SUCCESS);
            }
        });
    }


    public List<MyCityBus> getMyCityBus() {
        return mMyCityBusList;
    }

    public List<CityBus.DataBean> getBusList() {
        return busList;
    }

    public LiveData<State> getBusLivedata() {
        return busLivedata;
    }
}
